package im.composer.media.sound.misc;

import javax.sound.sampled.AudioFormat;

import org.tritonus.share.sampled.FloatSampleBuffer;
import org.tritonus.share.sampled.FloatSampleInput;

public abstract class SingleFloatBuffer implements FloatSampleInput {

	private final AudioFormat format;
	private FloatSampleBuffer buf = null;
	private int pos = 0;
	private boolean done = false;

	public SingleFloatBuffer(AudioFormat format) {
		this.format = format;
	}

	@Override
	public void read(FloatSampleBuffer buffer) {
		read(buffer, 0, buffer.getSampleCount());
	}

	@Override
	public void read(FloatSampleBuffer buffer, int offset, int sampleCount) {
		if (buf == null) {
			try {
				buf = readBuffer();
				pos = 0;
			} catch (Exception e) {
				done = true;
				buffer.setSampleCount(offset, true);
				return;
			}
		}
		int limit = Math.min(sampleCount, buf.getSampleCount() - pos);
		buffer.mix(buf, pos, offset, limit);
		buffer.setSampleCount(limit, true);
		if (pos + limit == buf.getSampleCount()) {
			buf = null;
			pos = 0;
		} else {
			pos += limit;
		}
	}

	protected abstract FloatSampleBuffer readBuffer() throws Exception;

	public void setBuffer(FloatSampleBuffer buf, int pos) {
		this.buf = buf;
		this.pos = pos;
	}

	@Override
	public boolean isDone() {
		return done;
	}

	@Override
	public int getChannels() {
		return format.getChannels();
	}

	@Override
	public float getSampleRate() {
		return format.getSampleRate();
	}

}
